const extend = require('extend');

const Question = require('./question');
const Buff = require('./buff');

class Runner {
    constructor(board, role) {
        this.board = board;
        this.role = role;

        this.level = 1;
        this.status = {
            question: {},
            answers: [],
            index: 0
        };
        this.rounds = 0;
        this.position = 0;
        this.lastWrong = 0;
        this.buffs = [];

        this.nextQuestion();
    }
    get game() {
        return this.board && this.board.game;
    }
    get filteredBuffs() {
        let now = +Date.now();
        let timeout = this.buffs.filter(buff => buff.start + buff.keep * 1000 <= now);
        for (let buff of timeout) {
            this.offBuff(buff);
        }
        return this.buffs = this.buffs.filter(buff => buff.start + buff.keep * 1000 > now);
    }
    buff(type, keep) {
        this.buffs = this.filteredBuffs.filter(buff => buff.type !== type);
        let buff = {
            type, keep, start: +Date.now()
        };
        buff.timer = setTimeout(() => this.game.checkBuff(this, buff), 1000);
        this.buffs.push(buff);
    }
    hasBuff(type) {
        return this.filteredBuffs.find(buff => buff.type === type);
    }
    checkBuff(buff) {
        let left = Buff.left(buff);
        if (left <= 0) {
            this.game.offBuff(this, buff);
        } else if (this.level) {
            buff.timer = setTimeout(() => this.game.checkBuff(this, buff), Math.min(left, 1000));
        }
    }
    offBuff(buff) {
        let buffs = this.buffs;
        let index = buffs.indexOf(buff);
        if (index !== -1) {
            clearTimeout(buff.timer);
            buffs.splice(index, 1);
            if (buff.type === Buff.types.vertigo) {
                this.nextQuestion();
            }
        }
    }
    clearBuffs() {
        for (let buff of this.buffs) {
            clearTimeout(buff.timer);
        }
        this.buffs = [];
    }

    doAnswer({ question, answer }) {
        if (this.level) {
            this.game.doAnswer(this, question, answer);
        }
    }

    attack() {
        this.position = Math.floor(this.position) + 0.75;
        this.resetTimer = setTimeout(() => this.game.rebound(this), 500);
    }

    rebound() {
        this.position = Math.floor(this.position);
    }

    clearReset() {
        clearTimeout(this.resetTimer);
    }

    nextQuestion() {
        let buff = this.hasBuff(Buff.types.vertigo);
        if (buff) {
            this.status = {
                question: {},
                answers: [],
                index: this.status.index + 1
            }
        } else {
            this.status = {
                ...Question.random(),
                index: this.status.index + 1
            };
        }
    }

    dead() {
        console.log(this.role.player.name + '已淘汰');
        this.status = {
            question: {},
            answers: []
        }
        this.level = 0;
        this.deadTime = +Date.now();
        this.clearReset();
        this.clearBuffs();
    }

    win() {
        this.level = 0;
        this.clearReset();
        this.clearBuffs();
    }

    upgrade(level) {
        if (this.level) {
            this.level += level;
        }
    }
    downgrade(level) {
        if (this.level) {
            this.level -= level;
        }
    }

    get data() {
        return extend(true, this.role.summary, {
            status: this.status,
            level: this.level,
            rounds: this.rounds,
            position: this.position,
            buffs: this.buffs.map(buff => ({ type: buff.type, title: Buff.titles[buff.type], left: Math.ceil(Buff.left(buff) / 1000) }))
        })
    }
}

module.exports = Runner;
